package sk.tuke.serviceDao;

import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

import org.hibernate.Query;
import org.hibernate.Session;

import sk.tuke.utils.HibernateUtil;

public class AbstractDao {

	public static Session getSession() {
		return HibernateUtil.getSessionFactory().openSession();
	}

	public <T> T findEntityByNumber(Class<T> clazz, int number) {
		Session session = getSession();
		session.beginTransaction();
		Query query = session.createQuery("FROM " + clazz.getCanonicalName() + " where number = :number");
		query.setLong("number", number);
		@SuppressWarnings("unchecked")
		T object = (T) query.uniqueResult();
		return object;
	}

	public <T> T findEntityByName(Class<T> clazz, String name) {
		Session session = getSession();
		session.beginTransaction();
		Query query = session.createQuery("FROM " + clazz.getCanonicalName() + " where name = :name");
		query.setString("name", name);
		@SuppressWarnings("unchecked")
		T object = (T) query.uniqueResult();
		return object;
	}

	@SuppressWarnings("unchecked")
	public <T> List<T> findEntityByNameWildCard(Class<T> clazz, String name) {
		Session session = getSession();
		session.beginTransaction();
		List<T> object = (List<T>) new ArrayList<Object>();
		Query query = session.createQuery("FROM " + clazz.getCanonicalName() + " where name like concat ('%', :name, '%')");
		query.setString("name", name);
		object.addAll(query.list());
		return object;
	}

	@SuppressWarnings("unchecked")
	public <T> List<T> findEntitiesByNames(Class<T> clazz, List<String> names) {
		Session session = getSession();
		session.beginTransaction();
		List<T> object = (List<T>) new ArrayList<Object>();
		Query query = session.createQuery("FROM " + clazz.getCanonicalName() + " where name = :names");
		query.setParameterList("names", names);
		object.addAll(query.list());
		return object;
	}

	@SuppressWarnings("unchecked")
	public <T> List<T> findEntitiesByNumbers(Class<T> clazz, List<?> numbers) {
		Session session = getSession();
		session.beginTransaction();
		List<T> object = (List<T>) new ArrayList<Object>();
		Query query = session.createQuery("FROM " + clazz.getCanonicalName() + " where number = :numbers");
		query.setParameterList("numbers", numbers);
		object.addAll(query.list());
		return object;
	}

	protected String generatePassword(String password) throws NoSuchAlgorithmException {
		MessageDigest messageDigest = MessageDigest.getInstance("SHA");
		if (password == null)
			password = UUID.randomUUID().toString();
		messageDigest.reset();
		messageDigest.update(password.getBytes());
		return byteArrayToHexString(messageDigest.digest());
	}

	private String byteArrayToHexString(byte[] b) {
		StringBuffer sb = new StringBuffer(b.length * 2);
		for (int i = 0; i < b.length; i++) {
			int v = b[i] & 0xff;
			if (v < 16) {
				sb.append('0');
			}
			sb.append(Integer.toHexString(v));
		}
		return sb.toString();
	}

}
